﻿/*
* <Wayland/WTK.h>
* Wayland实用工具库
* Copyright (c) 2014 第三界主 http://git.oschina.net/afxmain/WTK.git
*/

#include <stdint.h>
#include <cairo/cairo.h>
#include <wayland-client.h>
#include <linux/input.h>

/* 某些struct wl_开头的对象实际上是wl_proxy对象的id，与windows下的Handle类似。 */
/* Wayland句柄 */
typedef struct wl_display* HDISPLAY;
typedef struct wl_registry* HREGISTRY;
typedef struct wl_compositor* HCOMPOSITOR;
typedef struct wl_shell* HSHELL;
typedef struct wl_shm* HSHM;
typedef struct wl_shm_pool* HSHMPOOL;
typedef struct wl_seat* HSEAT;
typedef struct wl_pointer* HPOINTER;
typedef struct wl_surface* HSURFACE;
typedef struct wl_shell_surface * HSHELLSURFACE;
typedef struct wl_callback* HCALLBACK;
typedef struct wl_buffer* HBUFFER;
typedef struct wl_keyboard* HKEYBOARD;

typedef void* LPVOID;

typedef cairo_surface_t* HCAIROSURFACE;
typedef cairo_t* HCAIRO;

#define WL_TRUE		1
#define WL_FALSE	0
typedef unsigned BOOL;

typedef struct _WAYLANDGLOBALS
{
	HDISPLAY	s_display;		/* 所有API都需要wl_display */	
	HREGISTRY	s_registry;
	HCOMPOSITOR s_compositor;	/* 合成器 */
	HSHELL		s_shell;		/* 窗口操纵器，如移动窗口 */
	HSHM		s_shm;			/* 缓存管理器，与绘制相关 */
	uint32_t	shm_formats;	/* 支持的像素格式 */
	HSEAT		s_seat;			/* 输入设备管理器，管理键盘鼠标 */
	HPOINTER	s_pointer;		/* 鼠标控制器 */
	HKEYBOARD	s_keyboard;		/* 键盘控制器 */

	HSURFACE	s_pointer_surface;	/* 鼠标当前窗口 */
	HSURFACE	s_kb_surface;		/* 键盘当前窗口 */

} WAYLANDGLOBALS, *LPWAYLANDGLOBALS;



typedef struct _SIZE
{
	int width, height;
} SIZE;

/* 窗口内容缓存与绘图设备描述符，等同于Win32的HDC */

typedef struct _BUFFERPRIVATE
{
	int bBusy; // hBuffer是否被Wayland服务器锁定

	int stride;
	int length;
	SIZE sz;

	LPVOID			lpPixelBuffer;	/* memset(data, 0, witdh*height) */
} BUFFERPRIVATE, *LPBUFFERPRIVATE;


typedef struct _SURFACEPRIVATE
{
	HSURFACE		hSurface;	/* 窗口句柄 */
	HSHELLSURFACE	hShell;		/* 窗口操纵器句柄 */

	/* Wayland对缓存的使用方式是：
	Client commit
	Server lock->composite->release
	Client reuse
	*/
	HBUFFER hBuffers[2]; /* 两个缓存足够用了, 缓存大小由sz和shm_formats决定 */
	HSHMPOOL hShmPool;
} SURFACEPRIVATE, *LPSURFACEPRIVATE;


HSURFACE CreateSurface(const char* title, int width, int height); /* 窗口创建函数 */

int wlShowSurface(HSURFACE hSurface); /* 显示窗口，分配显示缓存，如果失败返回0 成功返回1 */

static inline LPSURFACEPRIVATE wlGetSurfacePrivate( HSURFACE hSurface ) {
	return (LPSURFACEPRIVATE)wl_surface_get_user_data(hSurface);
}

static void wlSetSurfacePrivate( HSURFACE hSurface, LPSURFACEPRIVATE lpSurfacePrivate ) {
	wl_surface_set_user_data(hSurface, lpSurfacePrivate);
}

static inline void wlSetPaintProc(HSURFACE surface, PAINTPROC lpfnPaintProc) { 
	wlGetSurfacePrivate(surface)->lpfnPaintProc = lpfnPaintProc; 
}

static inline void wlCallPaintProc(HSURFACE hSurface ) { 
	LPSURFACEPRIVATE lpSurfacePrivate = wlGetSurfacePrivate(hSurface);
	if(lpSurfacePrivate && lpSurfacePrivate->lpfnPaintProc)
	{
		lpSurfacePrivate->lpfnPaintProc(hSurface);
	}
}

static inline void wlSetPaintDone(HSURFACE hSurface, PAINTDONEPROC lpfnPaintDone) {
	wlGetSurfacePrivate(hSurface)->lpfnPaintDone = lpfnPaintDone;
}

void wlRequestPaintDone(HSURFACE hSurface); /* 请求绘制结束事件通知，在BeginPaint和EndPaint之间调用，只生效一次 */

static inline void wlSetPointerProc(HSURFACE hSurface, POINTERPROC lpfnPointerProc) {
	LPSURFACEPRIVATE lpSurfacePrivate = wlGetSurfacePrivate(hSurface);
	if(lpSurfacePrivate )
		lpSurfacePrivate->lpfnPointerProc = lpfnPointerProc;
}

static inline void wlCallPointerProc(HSURFACE hSurface, uint32_t button, uint32_t state, uint32_t serial) {
	LPSURFACEPRIVATE lpSurfacePrivate = wlGetSurfacePrivate(hSurface);
	if(lpSurfacePrivate && lpSurfacePrivate->lpfnPointerProc)
	{
		lpSurfacePrivate->lpfnPointerProc(hSurface, button, state, serial);
	}
}


static inline void wlSetKeyboardProc(HSURFACE surface, KEYBOARDPROC surfaceproc) { }

SIZE wlGetSurfaceSize(HSURFACE surface);


//////////////////////////////////////////////////////////////////////////
BOOL InitWayland();
